package it.cst.entity.dao;


import it.cst.entity.Group;
import it.cst.entity.Match;
import it.cst.entity.Player;
import it.cst.util.Utils;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
import org.hibernate.Criteria;
import org.hibernate.Query;
import org.hibernate.SessionFactory;
import org.hibernate.criterion.Order;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

@Repository
public class MatchDAOImpl implements MatchDAO{
	@Autowired
	private SessionFactory sessionFactory;
	private String pattern = "yyyy-MM-dd";
	private SimpleDateFormat sdf = new SimpleDateFormat(pattern);
	
	public SessionFactory getSessionFactory() {
		return sessionFactory;
	}

	public void setSessionFactory(SessionFactory sessionFactory) {
		this.sessionFactory = sessionFactory;
	}

	@Override
	public Integer addMatch(Match match) {
		sessionFactory.getCurrentSession().save(match);
		return match.getId();
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<Match> listMatch() {
		Criteria c = sessionFactory.getCurrentSession().createCriteria(Match.class);
		c.addOrder(Order.desc("id"));
		return c.list();
	}

	@Override
	public void removeMatch(Match match) {
		sessionFactory.getCurrentSession().delete(match);
	}

	@Override
	public Match getMatch(Integer id) {
		Match m = (Match) sessionFactory.getCurrentSession().get(Match.class, id);
		return m;
	}

	@Override
	public Match getLastMatch() {
		Criteria c = sessionFactory.getCurrentSession().createCriteria(Match.class);
		c.addOrder(Order.desc("id"));
		c.setMaxResults(1);
		Match m = (Match)c.uniqueResult();
		return m;
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<Match> listMatch(Integer num, Integer idMatch, String operator, String orderFlow) {
		Query q = null;
		String query = "from Match WHERE id " + operator + " ? ORDER BY id " + orderFlow;
		q = sessionFactory.getCurrentSession().createQuery(query);
		q.setInteger(0, idMatch);
		return q.setMaxResults(num).list();
	}

	
	
	
	@Override
	public Integer countMatch(Integer idMatch, String operator) {
		String query = "from Match WHERE id " + operator + " ?";
		Query q = sessionFactory.getCurrentSession().createQuery(query);
		q.setInteger(0, idMatch);
		return q.list().size();
	}

	
	public Integer countMatch() {
		String query = "from Match";
		Query q = null;
		q = sessionFactory.getCurrentSession().createQuery(query);
		return q.list().size();
	}

	
	
	
	@SuppressWarnings("unchecked")
	public List<Match> listMatch(Integer num) {
		String query = "from Match ORDER BY id DESC";
		Query q = null;
		q = sessionFactory.getCurrentSession().createQuery(query);
		return q.setMaxResults(num).list();
	}

	
	
	
	
	
	@SuppressWarnings({ "unchecked"})
	public List<Match> listMatch(Integer num, Integer idMatch, String operator,String orderFlow, String date,String user) {
		List<Match> ret = new ArrayList<Match>();
		String query = "from Match ORDER BY id DESC";
		Query q = null;
		if(date != null && user == null){
			query = "from Match WHERE id " + operator + " ? AND timestamp LIKE ? ORDER BY id " + orderFlow;
			q = sessionFactory.getCurrentSession().createQuery(query);
			q.setInteger(0, idMatch);
			q.setString(1,sdf.format(Utils.getDateFromJQMPicker(date)) + "%");
			ret = q.setMaxResults(num).list();	
		}
		else if(date == null && user != null){
			query = "from Match WHERE id " + operator + " ? ORDER BY id " + orderFlow;
			q = sessionFactory.getCurrentSession().createQuery(query);
			q.setInteger(0, idMatch);
			List<Match> ml = q.list();
			for(Match m : ml){
				for(Group g : m.getGroups()){
					for(Player p : g.getPlayers()){
						if(p.getUser().getUsername().equalsIgnoreCase(user)){
							if(ret.size() < num)
								ret.add(m);
						}
					}
				}
			}
		}
		else{
			query = "from Match WHERE id " + operator + " ? AND timestamp LIKE ? ORDER BY id " + orderFlow;
			q = sessionFactory.getCurrentSession().createQuery(query);
			q.setInteger(0, idMatch);
			q.setString(1,sdf.format(Utils.getDateFromJQMPicker(date)) + "%");
			List<Match> ml = q.list();
			for(Match m : ml){
				for(Group g : m.getGroups()){
					for(Player p : g.getPlayers()){
						if(p.getUser().getUsername().equalsIgnoreCase(user)){
							if(ret.size() < num)
								ret.add(m);
						}
					}
				}
			}			
		}
		return ret;
	}

	
	
	
	
	
	
	
	
	
	
	@SuppressWarnings({ "unchecked"})
	public Integer countMatch(Integer idMatch, String operator,String orderFlow, String date,String user) {
		Integer ret = 0;
		String query = "from Match ORDER BY id DESC";
		Query q = null;
		if(date != null && user == null){
			query = "from Match WHERE id " + operator + " ? AND timestamp LIKE ? ORDER BY id " + orderFlow;
			q = sessionFactory.getCurrentSession().createQuery(query);
			q.setInteger(0, idMatch);
			q.setString(1,sdf.format(Utils.getDateFromJQMPicker(date)) + "%");
			ret = q.list().size();	
		}
		else if(date == null && user != null){
			query = "from Match WHERE id " + operator + " ? ORDER BY id " + orderFlow;
			q = sessionFactory.getCurrentSession().createQuery(query);
			q.setInteger(0, idMatch);
			List<Match> ml = q.list();
			for(Match m : ml){
				for(Group g : m.getGroups()){
					for(Player p : g.getPlayers()){
						if(p.getUser().getUsername().equalsIgnoreCase(user)){
								ret++;
						}
					}
				}
			}
		}
		else{
			query = "from Match WHERE id " + operator + " ? AND timestamp LIKE ? ORDER BY id " + orderFlow;
			q = sessionFactory.getCurrentSession().createQuery(query);
			q.setInteger(0, idMatch);
			q.setString(1,sdf.format(Utils.getDateFromJQMPicker(date)) + "%");
			List<Match> ml = q.list();
			for(Match m : ml){
				for(Group g : m.getGroups()){
					for(Player p : g.getPlayers()){
						if(p.getUser().getUsername().equalsIgnoreCase(user)){
								ret++;
						}
					}
				}
			}			
		}
		return ret;
	}
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	@SuppressWarnings({"unchecked" })
	public List<Match> listMatch(Integer num, String date, String user) {
		List<Match> ret = new ArrayList<Match>();
		String query = "from Match ORDER BY id DESC";
		Query q = null;
		if(date != null && user == null){
			query = "from Match WHERE timestamp LIKE ? ORDER BY id DESC";
			q = sessionFactory.getCurrentSession().createQuery(query);
			q.setString(0,sdf.format(Utils.getDateFromJQMPicker(date)) + "%");
			ret = q.setMaxResults(num).list();	
		}
		else if(date == null && user != null){
			query = "from Match ORDER BY id DESC";
			q = sessionFactory.getCurrentSession().createQuery(query);
			List<Match> ml = q.list();
			for(Match m : ml){
				for(Group g : m.getGroups()){
					for(Player p : g.getPlayers()){
						if(p.getUser().getUsername().equalsIgnoreCase(user)){
							if(ret.size() < num)
								ret.add(m);
						}
					}
				}
			}
		}
		else{
			query = "from Match WHERE timestamp LIKE ? ORDER BY id DESC";
			q = sessionFactory.getCurrentSession().createQuery(query);
			q.setString(0,sdf.format(Utils.getDateFromJQMPicker(date)) + "%");
			List<Match> ml = q.list();
			for(Match m : ml){
				for(Group g : m.getGroups()){
					for(Player p : g.getPlayers()){
						if(p.getUser().getUsername().equalsIgnoreCase(user)){
							if(ret.size() < num)
								ret.add(m);
						}
					}
				}
			}			
		}
		return ret;
	}

	
	
	
	
	@SuppressWarnings({"unchecked" })
	public Integer countMatch(String date, String user) {
		Integer ret = 0;
		String query = "from Match ORDER BY id DESC";
		Query q = null;
		if(date != null && user == null){
			query = "from Match WHERE timestamp LIKE ? ORDER BY id DESC";
			q = sessionFactory.getCurrentSession().createQuery(query);
			q.setString(0,sdf.format(Utils.getDateFromJQMPicker(date)) + "%");
			ret = q.list().size();	
		}
		else if(date == null && user != null){
			query = "from Match ORDER BY id DESC";
			q = sessionFactory.getCurrentSession().createQuery(query);
			List<Match> ml = q.list();
			for(Match m : ml){
				for(Group g : m.getGroups()){
					for(Player p : g.getPlayers()){
						if(p.getUser().getUsername().equalsIgnoreCase(user)){
								ret++;
						}
					}
				}
			}
		}
		else{
			query = "from Match WHERE timestamp LIKE ? ORDER BY id DESC";
			q = sessionFactory.getCurrentSession().createQuery(query);
			q.setString(0,sdf.format(Utils.getDateFromJQMPicker(date)) + "%");
			List<Match> ml = q.list();
			for(Match m : ml){
				for(Group g : m.getGroups()){
					for(Player p : g.getPlayers()){
						if(p.getUser().getUsername().equalsIgnoreCase(user)){
								ret++;
						}
					}
				}
			}			
		}
		return ret;
	}

}
